package org.jeecg.modules.hc.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByOutTradeNoRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.boot.starter.lock.annotation.JLock;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.hc.constant.RedisConstant;
import org.jeecg.modules.hc.entity.*;
import org.jeecg.modules.hc.enums.*;
import org.jeecg.modules.hc.mapper.HcOrderMapper;
import org.jeecg.modules.hc.pcWxPay.config.WeChatConfig;
import org.jeecg.modules.hc.service.*;
import org.jeecg.modules.hc.utils.HcUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 订单
 * @Author: jeecg-boot
 * @Date: 2022-12-13
 * @Version: V1.0
 */
@Service
@Slf4j
public class HcOrderServiceImpl extends ServiceImpl<HcOrderMapper, HcOrder> implements IHcOrderService {

    @Autowired
    private IHcUserService hcUserService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IHcSiteAddressDetailsService hcSiteAddressDetailsService;

    @Autowired
    private IHcShoppingCartService hcShoppingCartService;

    @Autowired
    private IHcMerchantService hcMerchantService;

    @Autowired
    private IHcCommodityService hcCommodityService;

    @Autowired
    private IHcOrderDetailedService hcOrderDetailedService;

    @Autowired
    private IHcOrderMerchantService hcOrderMerchantService;

    @Autowired
    private IHcWalletService hcWalletService;

    @Autowired
    private IHcWxPayService hcWxPayService;

    @Autowired
    private IHcWxPayRefundService hcWxPayRefundService;

    @Autowired
    private IHcAliPayService hcAliPayService;

    @Autowired
    private IHcAliRefundService hcAliRefundService;

    @Lazy
    @Autowired
    private HcOrderServiceImpl hcOrderService;

    @Value("${wx.pay.privateKeyPath}")
    private String privateKeyPath ;

    @Transactional(rollbackFor = Exception.class)
    public HcOrder pay(HcOrder param) throws WxPayException, AlipayApiException {
        HcOrder hcOrder = new HcOrder();

        //获取用户信息和地址信息
        HcUser hcUser = hcUserService.getById(param.getUserId());

        if (!"native".equals(param.getWxPayType())){//在线支付不需要微信授权
            if ("jsapi".equals(param.getWxPayType()) && StringUtils.isBlank(hcUser.getOpenId())) {
                throw new JeecgBootException("请先授权微信登录");
            }
        }

        //根据用户获取大厦信息
        HcSiteAddressDetails hcSiteAddressDetails = hcUserService.checkAddress(hcUser);

        if (hcSiteAddressDetails.getState().equals(HcIsFlagEnum.NO)) {
            throw new JeecgBootException("您选择的大厦今天休息哦，具体营业时间可以问群里的工作人员！");
        }

        //保存商品id和购物车数量，用来判断库存是否足够
        Map<String, HcCommodity> commodityMap = new HashMap<>();
        Map<String, HcMerchant> merchantMap = new HashMap<>();

        //待支付总金额
        BigDecimal totalPrice = new BigDecimal(0);

        //获取需要支付的购物车信息
        for (String shoppingCartId : param.getShoppingCartIds()) {
            HcShoppingCart hcShoppingCart = hcShoppingCartService.getById(shoppingCartId);

            if (!hcShoppingCart.getUserId().equals(param.getUserId())) {
                throw new JeecgBootException("用户信息不匹配");
            }
            //商品信息
            HcCommodity hcCommodity = hcCommodityService.getById(hcShoppingCart.getCommodityId());

            if (hcCommodity.getUpFlag().equals(HcUpFlagEnum.NO)) {
                throw new JeecgBootException(hcCommodity.getTradeName() + "已下架，不能下单");
            }

            Boolean checkCommodity = hcShoppingCartService.checkCommodity(hcShoppingCart, hcCommodity, hcSiteAddressDetails.getId());

            if (checkCommodity == null || !checkCommodity) {
                throw new JeecgBootException("商品信息变更，请刷新重试");
            }

            //商户信息
            HcMerchant hcMerchant = hcMerchantService.getById(hcShoppingCart.getMerchantId());
            hcMerchantService.setInformation(hcMerchant);

            if (HcBusinessStateEnum.NO.equals(hcMerchant.getBusinessState()) || HcBusinessStateEnum.NO_ADMIN.equals(hcMerchant.getBusinessState())) {
                throw new JeecgBootException(hcMerchant.getStoreName() + "打烊中不能下单");
            } else {
                hcMerchantService.checkBusinessState(hcMerchant);

                if (HcBusinessStateEnum.NO.equals(hcMerchant.getBusinessState()) || HcBusinessStateEnum.NO_ADMIN.equals(hcMerchant.getBusinessState())) {
                    throw new JeecgBootException(hcMerchant.getStoreName() + "打烊中不能下单");
                }
            }

            if (!hcMerchant.getSiteId().contains(hcSiteAddressDetails.getSiteId())) {
                throw new JeecgBootException(hcMerchant.getStoreName() + "不在配送范围内，请重新下单");
            }

            if (commodityMap.containsKey(hcCommodity.getId())) {
                hcCommodity = commodityMap.get(hcCommodity.getId());
            }

            //保存商品数量
            Integer shoppingCartCount = 0;

            shoppingCartCount += hcShoppingCart.getCommodityQuantity();
            hcCommodity.setShoppingCartCount(shoppingCartCount);
            commodityMap.put(hcCommodity.getId(), hcCommodity);

            totalPrice = totalPrice.add(hcShoppingCart.getCommodityPrice());

            if (merchantMap.containsKey(hcShoppingCart.getMerchantId())) {
                hcMerchant = merchantMap.get(hcShoppingCart.getMerchantId());
            }

            List<HcShoppingCart> hcShoppingCartList = hcMerchant.getHcShoppingCartList() == null ? new ArrayList<>() : hcMerchant.getHcShoppingCartList();
            HcShoppingCart target = new HcShoppingCart();
            BeanUtils.copyProperties(hcShoppingCart, target, "hcMerchant");
            hcShoppingCartList.add(target);
            hcMerchant.setHcShoppingCartList(hcShoppingCartList);
            merchantMap.put(hcShoppingCart.getMerchantId(), hcMerchant);
        }

        if (totalPrice.compareTo(new BigDecimal(0)) <= 0) {
            throw new JeecgBootException("当前商品价格设置有误，请您选择其他商品进行下单！");
        }

        List<HcMerchant> hcMerchantShoppingList = merchantMap.values().stream().collect(Collectors.toList());
        hcShoppingCartService.checkCommodityRequired(hcMerchantShoppingList, null);

        //判断库存
        for (String key : commodityMap.keySet()) {
            HcCommodity hcCommodity = commodityMap.get(key);

            if (hcCommodity.getLimitBuy() > -1) {
                Integer remainingQuantity = hcCommodityService.getRemainingQuantity(hcCommodity);

                if (remainingQuantity < hcCommodity.getShoppingCartCount()) {
                    throw new JeecgBootException(hcCommodity.getTradeName() + " 库存不足");
                }
            }
        }

        hcUserService.setWalletBalance(hcUser);

        if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET)) {
            if (hcUser.getWalletBalance().compareTo(totalPrice) < 0) {
                throw new JeecgBootException("钱包余额不足");
            }
        } else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WXPAY) || param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_WXPAY)) {
            BigDecimal payAmount;

            if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_WXPAY)) {
                if (hcUser.getWalletBalance().compareTo(new BigDecimal(0)) <= 0) {
                    throw new JeecgBootException("钱包余额不足");
                }

                if (hcUser.getWalletBalance().compareTo(totalPrice) >= 0) {
                    throw new JeecgBootException("请使用钱包付款");
                }

                payAmount = totalPrice.subtract(hcUser.getWalletBalance());
            } else {
                payAmount = totalPrice;
            }

            if (payAmount.compareTo(new BigDecimal(0)) > 0) {
                HcWxPay hcWxPay = hcWxPayService.pay(param.getWxPayType(), param.getUserId(), hcUser.getOpenId(), "用膳团", payAmount);
                hcOrder.setHcWxPay(hcWxPay);
                hcOrder.setPaymentId(hcWxPay.getId());
            }
        } else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.ALIPAY) || param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_ALIPAY)) {
            BigDecimal payAmount;

            if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_ALIPAY)) {
                if (hcUser.getWalletBalance().compareTo(new BigDecimal(0)) <= 0) {
                    throw new JeecgBootException("钱包余额不足");
                }

                if (hcUser.getWalletBalance().compareTo(totalPrice) >= 0) {
                    throw new JeecgBootException("请使用钱包付款");
                }

                payAmount = totalPrice.subtract(hcUser.getWalletBalance());
            } else {
                payAmount = totalPrice;
            }

            if (payAmount.compareTo(new BigDecimal(0)) > 0) {
                HcAliPay hcAliPay = hcAliPayService.pay(param.getUserId(), payAmount);
                hcOrder.setHcAliPay(hcAliPay);
                hcOrder.setPaymentId(hcAliPay.getId());
            }
        }else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.PC_WX)){//微信扫码支付

//            HcWxPay hcWxPay = hcWxPayService.preNativePay(param.getUserId(), "用膳团", totalPrice);
//            hcOrder.setHcWxPay(hcWxPay);
//            hcOrder.setPaymentId(hcWxPay.getId());

        }else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.PC_ZFB)){//支付宝扫码支付

            HcAliPay hcAliPay = hcAliPayService.preNativePay(param.getUserId(),  totalPrice);
            hcOrder.setHcAliPay(hcAliPay);
            hcOrder.setPaymentId(hcAliPay.getId());

        }

        //保存订单
        hcOrder.setUserId(param.getUserId());
        hcOrder.setPaymentMethod(param.getPaymentMethod());
        hcOrder.setState(HcOrderStateEnum.WAIT);
        hcOrder.setObjectJson(JSON.toJSONString(param));
        this.save(hcOrder);

        hcOrder.setObjectJson("");
        return hcOrder;
    }

    public void checkNoPayOrder(String userId) {
        List<HcOrder> hcOrderList = this.list(new LambdaQueryWrapper<HcOrder>()
                .eq(HcOrder::getUserId, userId)
                .eq(HcOrder::getState, HcOrderStateEnum.WAIT)
        );

        if (!CollectionUtils.isEmpty(hcOrderList)) {
            for (HcOrder hcOrder : hcOrderList) {
                try {
                    hcOrderService.queryResult(hcOrder);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void notifyOrder(WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result) {
        if (HcWxPayStateEnum.SUCCESS.getValue().equals(wxPayOrderNotifyV3Result.getResult().getTradeState())) {
            HcWxPay one = hcWxPayService.getOne(new LambdaQueryWrapper<HcWxPay>()
                    .eq(HcWxPay::getOutTradeNo, wxPayOrderNotifyV3Result.getResult().getOutTradeNo())
            );

            one.setSuccessTime(DateUtil.parse(wxPayOrderNotifyV3Result.getResult().getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"));
            one.setTradeState(HcWxPayStateEnum.SUCCESS.getValue());
            hcWxPayService.updateById(one);

            HcOrder hcOrder = this.getOne(new LambdaQueryWrapper<HcOrder>()
                    .eq(HcOrder::getPaymentId, one.getId())
                    .in(HcOrder::getPaymentMethod, HcPaymentMethodEnum.WXPAY, HcPaymentMethodEnum.WALLET_WXPAY)
            );

            //获取下单时保存的订单信息
            HcOrder order = JSON.parseObject(hcOrder.getObjectJson(), HcOrder.class);
            order.setId(hcOrder.getId());
            order.setHcWxPay(one);
            hcOrderService.createOrder(order);
        }
    }

    //查询支付结果
    @JLock(lockKey = "'queryResult'.concat(#param.id)")
    public HcOrder queryResult(HcOrder param) throws AlipayApiException, WxPayException {
        System.out.println("queryResult beigin ==============");
        HcOrder result = null;
        HcOrder hcOrder = this.getById(param.getId());

        if (!hcOrder.getState().equals(HcOrderStateEnum.WAIT)) {
            return hcOrder;
        }

        List<HcOrderMerchant> list = hcOrderMerchantService.list(new LambdaQueryWrapper<HcOrderMerchant>()
                .eq(HcOrderMerchant::getOrderId, hcOrder.getId())
        );

        if (!CollectionUtils.isEmpty(list)) {
            throw new JeecgBootException("数据异常，请检查订单数据");
        }

        //获取下单时保存的订单信息
        HcOrder order = JSON.parseObject(hcOrder.getObjectJson(), HcOrder.class);
        order.setId(hcOrder.getId());

        if (hcOrder.getPaymentMethod().equals(HcPaymentMethodEnum.WXPAY) || hcOrder.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_WXPAY)) {
            HcWxPay hcWxPay = hcWxPayService.queryPay(hcOrder.getPaymentId());

            if (HcWxPayStateEnum.SUCCESS.getValue().equals(hcWxPay.getTradeState())) {
                order.setHcWxPay(hcWxPay);
                try {
                    result = hcOrderService.createOrder(order);
                } catch (Exception e) {
                    HcWxPay wxPay = hcWxPayService.getById(hcOrder.getPaymentId());
                    HcWxPayRefund refund = hcWxPayRefundService.refund(wxPay.getOutTradeNo(), hcOrder.getUserId(), wxPay.getAmountTotal(), new BigDecimal(wxPay.getAmountTotal()).divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
                    this.updateById(new HcOrder().setId(hcOrder.getId()).setRefundId(refund.getId()));
                    e.printStackTrace();
                    throw new JeecgBootException(e.getMessage() + ", 如已付款，稍后将原路退回");
                }
            } else if (HcWxPayStateEnum.CLOSED.getValue().equals(hcWxPay.getTradeState())) {
                this.updateById(new HcOrder().setId(hcOrder.getId()).setState(HcOrderStateEnum.CANCELED));
            } else if (HcWxPayStateEnum.REFUND.getValue().equals(hcWxPay.getTradeState())) {
                this.updateById(new HcOrder().setId(hcOrder.getId()).setState(HcOrderStateEnum.CANCELED));
            } else if (HcWxPayStateEnum.NOTPAY.getValue().equals(hcWxPay.getTradeState())) {
                //下单15分钟后如果支付状态还是未支付 则更新状态
                Calendar instance = Calendar.getInstance();
                instance.setTime(hcOrder.getCreateTime());
                int m = DateUtils.dateDiff('m', Calendar.getInstance(), instance);

                if (m > 15) {
                    this.updateById(new HcOrder().setId(hcOrder.getId()).setState(HcOrderStateEnum.NOTPAY));
                }
            }
        } else if (hcOrder.getPaymentMethod().equals(HcPaymentMethodEnum.ALIPAY) || hcOrder.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_ALIPAY)) {
            HcAliPay aliPay = hcAliPayService.queryPay(hcOrder.getPaymentId());

            if (HcAliPayStateEnum.TRADE_SUCCESS.getValue().equals(aliPay.getTradeStatus())) {
                order.setHcAliPay(aliPay);
                try {
                    result = hcOrderService.createOrder(order);
                } catch (Exception e) {
                    HcAliPay hcAliPay = hcAliPayService.getById(hcOrder.getPaymentId());
                    HcAliRefund refund = hcAliRefundService.refund(hcAliPay.getOutTradeNo(), hcOrder.getUserId(), hcAliPay.getTotalAmount());
                    this.updateById(new HcOrder().setId(hcOrder.getId()).setRefundId(refund.getId()));
                    e.printStackTrace();
                    throw new JeecgBootException(e.getMessage() + ", 如已付款，稍后将原路退回");
                }
            } else if (HcAliPayStateEnum.TRADE_CLOSED.getValue().equals(aliPay.getTradeStatus())) {
                this.updateById(new HcOrder().setId(hcOrder.getId()).setState(HcOrderStateEnum.CANCELED));
            }
        } else if (hcOrder.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET)) {
            result = hcOrderService.createOrder(order);
        }

        return result;
    }
    @Override
    public HcWxPay queryNativePay(String outTradeNum) {
        //查询订单对象
        HcWxPay hcWxPay = hcWxPayService.getOne(new LambdaQueryWrapper<HcWxPay>().eq(HcWxPay::getOutTradeNo, outTradeNum));

        if (null == hcWxPay){
            throw new JeecgBootException("订单编号有勿");
        }

        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(WeChatConfig.merchantId)
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(WeChatConfig.merchantSerialNumber)
                        .apiV3Key(WeChatConfig.apiV3Key)
                        .build();
        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();
        QueryOrderByOutTradeNoRequest req = new QueryOrderByOutTradeNoRequest();
        req.setMchid(WeChatConfig.merchantId);
        req.setOutTradeNo(outTradeNum);
        //查询订单信息
        Transaction transaction = service.queryOrderByOutTradeNo(req);
        if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())){
            hcWxPay.setSuccessTime(DateUtil.parse(transaction.getSuccessTime(), "yyyy-MM-dd'T'HH:mm:ssXXX"));
            hcWxPay.setTradeState(HcWxPayStateEnum.SUCCESS.getValue());
            hcWxPayService.updateById(hcWxPay);

            HcOrder hcOrder = hcOrderService.getOne(new LambdaQueryWrapper<HcOrder>()
                    .eq(HcOrder::getPaymentId, hcWxPay.getId())
                    .in(HcOrder::getPaymentMethod, HcPaymentMethodEnum.PC_WX)
            );
            //获取下单时保存的订单信息
            HcOrder order = JSON.parseObject(hcOrder.getObjectJson(), HcOrder.class);
            order.setId(hcOrder.getId());
            order.setHcWxPay(hcWxPay);
            HcOrder order1 = hcOrderService.createOrder(order);
            hcWxPay.setId(order1.getId());
        }

        return hcWxPay;
    }

    @Transactional(rollbackFor = Exception.class)
    @JLock(lockKey = "#param.id")
    public HcOrder createOrder(HcOrder param) {
        HcOrder byId = this.getById(param.getId());

        if (!byId.getState().equals(HcOrderStateEnum.WAIT)) {
            return byId;
        }
        //获取用户信息和地址信息
        HcUser hcUser = hcUserService.getById(param.getUserId());
        HcSiteAddressDetails hcSiteAddressDetails = hcUserService.checkAddress(hcUser);

        if (hcSiteAddressDetails.getState().equals(HcIsFlagEnum.NO)) {
            throw new JeecgBootException("您选择的大厦今天休息哦，具体营业时间可以问群里的工作人员！");
        }

        //更新订单
        HcOrder hcOrder = new HcOrder();
        hcOrder.setId(param.getId());
        hcOrder.setPayTime(new Date());
        hcOrder.setRiderId(hcSiteAddressDetails.getNameRider());
        hcOrder.setState(HcOrderStateEnum.PAY);

        //判断是否已经下过单，如果没下过单判断此订单是否有分享人id，有则保存
        HcOrder one = this.getOne(new LambdaQueryWrapper<HcOrder>()
                .eq(HcOrder::getUserId, param.getUserId())
                .last(" limit 1 ")
        );

        if (one == null && StringUtils.isNotBlank(param.getShareUserId())) {
            hcOrder.setShareUserId(param.getShareUserId());
        }

        this.updateById(hcOrder);

        //保存商品id和购物车数量，用来判断库存是否足够
        Map<String, HcCommodity> commodityMap = new HashMap<>();

        //先根据商户id区分购物车数据
        Map<String, List<HcShoppingCart>> shoppingCartMap = new HashMap<>();

        for (String shoppingCartId : param.getShoppingCartIds()) {
            HcShoppingCart hcShoppingCart = hcShoppingCartService.getById(shoppingCartId);

            if (null!=hcShoppingCart){
//            if (!hcShoppingCart.getUserId().equals(param.getUserId())) {
//                throw new JeecgBootException("用户信息不匹配");
//            }

                HcCommodity hcCommodity = hcCommodityService.getById(hcShoppingCart.getCommodityId());

                Boolean checkCommodity = hcShoppingCartService.checkCommodity(hcShoppingCart, hcCommodity, hcSiteAddressDetails.getId());

//            if (checkCommodity == null || !checkCommodity) {
//                throw new JeecgBootException("商品信息变更，请刷新重试");
//            }

                hcShoppingCart.setHcCommodity(hcCommodity);

                List<HcShoppingCart> mapVal = new ArrayList<>();

                //保存购物车数据
                if (shoppingCartMap.containsKey(hcShoppingCart.getMerchantId())) {
                    mapVal = shoppingCartMap.get(hcShoppingCart.getMerchantId());
                }

                mapVal.add(hcShoppingCart);
                shoppingCartMap.put(hcShoppingCart.getMerchantId(), mapVal);

                //保存商品数量
                Integer shoppingCartCount = 0;

                if (commodityMap.containsKey(hcCommodity.getId())) {
                    hcCommodity = commodityMap.get(hcCommodity.getId());
                }

                shoppingCartCount += hcShoppingCart.getCommodityQuantity();
                hcCommodity.setShoppingCartCount(shoppingCartCount);
                commodityMap.put(hcCommodity.getId(), hcCommodity);
            }
        }

        //判断库存
        for (String key : commodityMap.keySet()) {
            HcCommodity hcCommodity = commodityMap.get(key);

            if (null != hcCommodity){
                if (hcCommodity.getLimitBuy() > -1) {
                    Integer remainingQuantity = hcCommodityService.getRemainingQuantity(hcCommodity);

                    if (remainingQuantity < hcCommodity.getShoppingCartCount()) {
                        throw new JeecgBootException(hcCommodity.getTradeName() + " 库存不足");
                    }
                }
            }
        }

        //获取取餐序号
        JSONObject yongShanTuanTime = HcUtils.getYongShanTuanTime();
        String beginTime = yongShanTuanTime.getString("beginTime");
        String endTime = yongShanTuanTime.getString("endTime");

        String redisKey = RedisConstant.HC_ORDER_NO + beginTime + endTime + "_" + hcSiteAddressDetails.getSiteId();
        int pickingSerialNo = 1;

        if (redisUtil.hasKey(redisKey)) {
            pickingSerialNo = (int) redisUtil.incr(redisKey, 1);
        } else {
            redisUtil.set(redisKey, 1, 60 * 60 * 24);
        }

        log.info("取餐序号：{}，Redis-key：{}", pickingSerialNo, redisKey);

        BigDecimal allPrice = new BigDecimal(0);

        for (String merchantId : shoppingCartMap.keySet()) {
            //保存商家订单
            HcOrderMerchant hcOrderMerchant = new HcOrderMerchant();
            hcOrderMerchant.setUserId(param.getUserId());
            hcOrderMerchant.setOrderId(hcOrder.getId());
            hcOrderMerchant.setState(HcOrderStateEnum.PAY);
            hcOrderMerchant.setNameTakingMeal(hcUser.getNameTakingMeal());
            hcOrderMerchant.setPhoneTakingMeals(hcUser.getPhoneTakingMeals());
            hcOrderMerchant.setPickingAddress(hcSiteAddressDetails.getAddressName() + hcUser.getSupplyAddressName());
            //panjixiang
//            if (("yes").equals(hcSiteAddressDetails.getEnableWriteAddress().getValue())) {
//                hcOrderMerchant.setSupplyAddress(hcUser.getSupplyAddressCode() + hcUser.getSupplyHomeCode());
//            } else {
//                hcOrderMerchant.setSupplyAddress(hcUser.getSupplyAddressCode());
//            }
            hcOrderMerchant.setAddressId(hcUser.getAddressId());

            if (param.getRemarksObj() != null) {
                if (param.getRemarksObj().containsKey(merchantId)) {
                    hcOrderMerchant.setRemarks(param.getRemarksObj().getString(merchantId));
                }
            }

            HcMerchant hcMerchant = hcMerchantService.getById(merchantId);
            hcMerchantService.setInformation(hcMerchant);

            if (HcBusinessStateEnum.NO.equals(hcMerchant.getBusinessState()) || HcBusinessStateEnum.NO_ADMIN.equals(hcMerchant.getBusinessState())) {
                throw new JeecgBootException(hcMerchant.getStoreName() + "打烊中不能下单");
            } else {
                hcMerchantService.checkBusinessState(hcMerchant);

                if (HcBusinessStateEnum.NO.equals(hcMerchant.getBusinessState()) || HcBusinessStateEnum.NO_ADMIN.equals(hcMerchant.getBusinessState())) {
                    throw new JeecgBootException(hcMerchant.getStoreName() + "打烊中不能下单");
                }
            }

            if (!hcMerchant.getSiteId().contains(hcSiteAddressDetails.getSiteId())) {
                throw new JeecgBootException(hcMerchant.getStoreName() + "不在配送范围内，请重新下单");
            }

            hcOrderMerchant.setMerchantId(hcMerchant.getId());
            hcOrderMerchant.setStoreDescription(hcMerchant.getStoreDescription());
            hcOrderMerchant.setStoreName(hcMerchant.getStoreName());
            hcOrderMerchant.setLogo(hcMerchant.getLogo());
            hcOrderMerchant.setPickingSerialNo(pickingSerialNo);
            hcOrderMerchant.setCreateBy("admin");

            if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_WXPAY) || param.getPaymentMethod().equals(HcPaymentMethodEnum.WXPAY)) {
                hcOrderMerchant.setCreateTime(param.getHcWxPay().getSuccessTime());
            } else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_ALIPAY) || param.getPaymentMethod().equals(HcPaymentMethodEnum.ALIPAY)) {
                hcOrderMerchant.setCreateTime(param.getHcAliPay().getSuccessTime());
            }

            hcOrderMerchantService.save(hcOrderMerchant);

            BigDecimal totalPrice = new BigDecimal(0);
            BigDecimal commodityPrice = new BigDecimal(0);
            BigDecimal commission = new BigDecimal(0);
            List<HcShoppingCart> hcShoppingCarts = shoppingCartMap.get(merchantId);

            List<HcOrderDetailed> hcOrderDetailedList = new ArrayList<>();

            for (HcShoppingCart hcShoppingCart : hcShoppingCarts) {
                //保存订单明细
                HcOrderDetailed hcOrderDetailed = new HcOrderDetailed();
                hcOrderDetailed.setOrderId(hcOrder.getId());
                hcOrderDetailed.setOrderMerchantId(hcOrderMerchant.getId());

                HcCommodity hcCommodity = hcShoppingCart.getHcCommodity();
                HcCommodity checkSpecifications = hcCommodityService.checkSpecifications(hcCommodity, hcSiteAddressDetails.getId(), hcShoppingCart.getCommoditySpecifications());

                if (hcCommodity.getSpecificationsFlag().equals(HcIsFlagEnum.YES)) {
                    hcOrderDetailed.setCommoditySpecifications(checkSpecifications.getCommoditySpecifications());
                    hcOrderDetailed.setSpecifications(checkSpecifications.getSpecifications());
                }

                hcOrderDetailed.setCommodityId(hcCommodity.getId());
                hcOrderDetailed.setCommodityQuantity(hcShoppingCart.getCommodityQuantity());
                hcOrderDetailed.setCommodityPrice(hcShoppingCart.getCommodityPrice());
                hcOrderDetailed.setTradeName(hcCommodity.getTradeName());
                hcOrderDetailed.setProductPicture(hcCommodity.getProductPicture());
                hcOrderDetailed.setCommission(checkSpecifications.getCommission().multiply(new BigDecimal(hcShoppingCart.getCommodityQuantity())));
                hcOrderDetailed.setCreateBy("admin");
                hcOrderDetailed.setCreateTime(new Date());
                hcOrderDetailedList.add(hcOrderDetailed);

                allPrice = allPrice.add(hcOrderDetailed.getCommodityPrice());
                totalPrice = totalPrice.add(hcOrderDetailed.getCommodityPrice());
                commodityPrice = commodityPrice.add(hcOrderDetailed.getCommodityPrice().subtract(hcOrderDetailed.getCommission()));
                commission = commission.add(hcOrderDetailed.getCommission());
            }

            //保存订单明细
            hcOrderDetailedService.saveBatch(hcOrderDetailedList);

            //更新商家订单总金额
            hcOrderMerchantService.updateById(new HcOrderMerchant()
                    .setId(hcOrderMerchant.getId())
                    .setTotalPrice(totalPrice)
                    .setCommodityPrice(commodityPrice)
                    .setCommission(commission)
            );
        }

        hcUserService.setWalletBalance(hcUser);

        HcWallet wallet = new HcWallet()
                .setUserId(param.getUserId())
                .setSource(HcWalletSourceEnum.PAY)
                .setRelationId(hcOrder.getId())
                .setCreateBy("admin")
                .setCreateTime(new Date());

        if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET)) {
            if (hcUser.getWalletBalance().compareTo(allPrice) < 0) {
                throw new JeecgBootException("钱包余额不足");
            }

            wallet.setAmount(allPrice.negate());
            hcWalletService.save(wallet);
        } else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_WXPAY)) {
            if (hcUser.getWalletBalance().compareTo(new BigDecimal(0)) <= 0) {
                throw new JeecgBootException("钱包余额不足");
            }
            System.out.println("============= 总付款金额 元：" + allPrice);
            BigDecimal subtract = allPrice.subtract(new BigDecimal(param.getHcWxPay().getAmountTotal()).divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
            System.out.println("============= 微信付款金额 分：" + param.getHcWxPay().getAmountTotal());
            System.out.println("============= 钱包付款金额 元：" + subtract);

            wallet.setAmount(subtract.negate());
            hcWalletService.save(wallet);
        } else if (param.getPaymentMethod().equals(HcPaymentMethodEnum.WALLET_ALIPAY)) {
            if (hcUser.getWalletBalance().compareTo(new BigDecimal(0)) <= 0) {
                throw new JeecgBootException("钱包余额不足");
            }
            System.out.println("============= 总付款金额 元：" + allPrice);
            BigDecimal subtract = allPrice.subtract(param.getHcAliPay().getTotalAmount());
            System.out.println("============= 支付宝付款金额 元：" + param.getHcAliPay().getTotalAmount());
            System.out.println("============= 钱包付款金额 元：" + subtract);
            wallet.setAmount(subtract.negate());
            hcWalletService.save(wallet);
        }

        //把钱包id更新到订单中
        if (StringUtils.isNotBlank(wallet.getId())) {
            this.updateById(new HcOrder().setId(param.getId()).setPaymentWalletId(wallet.getId()));
        }

        //获取下单的菜品名称
        HcOrderDetailed hcOrderDetailed = hcOrderDetailedService.getOne(new QueryWrapper<HcOrderDetailed>()
                .select("GROUP_CONCAT(TRADE_NAME Separator '+') as tradeName")
                .eq("ORDER_ID", hcOrder.getId())
        );

        //删除购物车数据
        hcShoppingCartService.removeByIds(param.getShoppingCartIds());

        //减少库存以及清除购物车缓存
        for (String key : commodityMap.keySet()) {
            HcCommodity hcCommodity = commodityMap.get(key);
            String redisLimitBuyKey = RedisConstant.HC_COMMODITY_LIMITBUY + beginTime + endTime + '_' + key;

            if (hcCommodity.getLimitBuy() > -1) {
                redisUtil.decr(redisLimitBuyKey, hcCommodity.getShoppingCartCount());
            }

            redisUtil.hdel(RedisConstant.HC_SHOPPING + param.getUserId(), key);
        }

        return new HcOrder()
                .setId(hcOrder.getId())
                .setState(HcOrderStateEnum.PAY);
    }
}
